package com.ds.esd.bpm.custom.action;

import com.ds.bpm.client.*;
import com.ds.bpm.client.data.DataMap;
import com.ds.bpm.engine.BPMException;
import com.ds.bpm.engine.WorkflowClientService;
import com.ds.bpm.engine.query.BPMCondition;
import com.ds.bpm.engine.query.BPMConditionKey;
import com.ds.bpm.enums.right.RightConditionEnums;
import com.ds.common.JDSException;
import com.ds.common.query.Operator;
import com.ds.common.query.Order;
import com.ds.config.ErrorListResultModel;
import com.ds.config.ListResultModel;
import com.ds.config.TreeListResultModel;
import com.ds.context.JDSActionContext;
import com.ds.enums.db.MethodChinaName;
import com.ds.esd.bpm.form.TableFormTabs;
import com.ds.esd.bpm.worklist.view.ActivityInstListView;
import com.ds.esd.client.ESDFacrory;
import com.ds.esd.client.Project;
import com.ds.esd.custom.ESDClass;
import com.ds.esd.custom.annotation.DialogAnnotation;
import com.ds.esd.custom.annotation.GridViewAnnotation;
import com.ds.esd.custom.annotation.nav.NavTabsViewAnnotation;
import com.ds.esd.custom.api.annotation.APIEventAnnotation;
import com.ds.esd.custom.api.enums.CustomCallBack;
import com.ds.esd.custom.api.enums.RequestPathEnum;
import com.ds.esd.custom.api.enums.ResponsePathEnum;
import com.ds.esd.custom.bean.ApiClassConfig;
import com.ds.esd.custom.bean.MethodConfig;
import com.ds.esd.custom.enums.CustomMenuItem;
import com.ds.esd.custom.module.annotation.ModuleAnnotation;
import com.ds.esd.custom.toolbar.bpm.RouteCustomMenu;
import com.ds.esd.dsm.DSMFactory;
import com.ds.esd.dsm.aggregation.DomainInst;
import com.ds.esd.dsm.repository.database.proxy.DSMTableProxy;
import com.ds.jds.core.esb.EsbUtil;
import com.ds.web.util.PageUtil;
import net.sf.cglib.beans.BeanMap;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.*;

@Controller
@RequestMapping(path = "/bpm/processdef/")
@MethodChinaName(cname = "流程定义", imageClass = "bpmfont bpmgongzuoliuzhutiguizeweihuguanli")
public class ProcessDefRowAction {


    @RouteCustomMenu(routeType = {RouteToType.Reload})
    @NavTabsViewAnnotation()
    @RequestMapping(method = RequestMethod.POST, value = "NewProcess")
    @APIEventAnnotation(customRequestData = {RequestPathEnum.treegridrow, RequestPathEnum.ctx}, customResponseData = ResponsePathEnum.form, autoRun = true, callback = CustomCallBack.ReloadMenu)
    @DialogAnnotation
    @ModuleAnnotation(dynLoad = true, imageClass = "bpmfont bpmgongzuoliuzhutiguizeweihuguanli", caption = "新建流程", name = "table")
    public @ResponseBody
    TreeListResultModel<List<TableFormTabs>> newProcess(String processDefVersionId, String domainId, String projectName) {
        TreeListResultModel<List<TableFormTabs>> formTabsTree = new TreeListResultModel<>();
        Map<String, Object> baseMap = new HashMap<>();
        try {
            ProcessDefVersion version = getClient().getProcessDefVersion(processDefVersionId);
            ProcessInst processInst = getClient().newProcess(version.getProcessDefId(), null, null, null);
            ActivityInst activityInst = processInst.getActivityInstList().get(0);
            String activityInstId = activityInst.getActivityInstId();
            baseMap.put("activityInstId", activityInstId);
            JDSActionContext.getActionContext().getContext().putAll(baseMap);
            List<TableFormTabs> formTabs = new ArrayList<>();
            ProcessDefVersion processDefVersion = activityInst.getProcessDefVersion();
            ProcessDefForm processDefForm = processDefVersion.getFormDef();
            Project project = ESDFacrory.getESDClient().getProjectByName(projectName);
            if (domainId == null || domainId.equals("")) {
                domainId = project.getProjectName();
            }
            List<String> tableNams = processDefForm.getTableNames();
            DomainInst domainInst = DSMFactory.getInstance().getAggregationManager().getDomainInstById(domainId);
            for (String tableName : tableNams) {
                DSMTableProxy proxy = DSMFactory.getInstance().getRepositoryManager().getTableProxyByName(tableName, projectName);
                TableFormTabs tableFormTab = new TableFormTabs();
                tableFormTab.setActivityInstId(activityInstId);
                tableFormTab.setConfigKey(proxy.getConfigKey());
                tableFormTab.setFormname(proxy.getFieldName());
                tableFormTab.setTableName(tableName);
                tableFormTab.setProcessInstId(processInst.getProcessInstId());
                tableFormTab.setId(proxy.getFieldName());
                tableFormTab.setCaption(proxy.getCnname());
                tableFormTab.setProcessDefVersionId(processDefVersion.getProcessDefVersionId());
                Map<String, String> tableMap = new HashMap<>();
                baseMap.put("tableName", tableName);
                baseMap.put("configKey", proxy.getConfigKey());
                if (tableFormTab.getTagVar() == null) {
                    tableFormTab.setTagVar(new HashMap<>());
                }
                tableFormTab.getTagVar().putAll(baseMap);
                ESDClass daoService = domainInst.getDAOService(tableName);
                if (daoService != null) {
                    ApiClassConfig apiClassConfig = DSMFactory.getInstance().getAggregationManager().getApiClassConfig(daoService.getClassName(), domainId);
                    MethodConfig methodConfig = apiClassConfig.getMethodByItem(CustomMenuItem.tabEditor);
                    if (methodConfig == null) {
                        methodConfig = apiClassConfig.getMethodByItem(CustomMenuItem.editor);
                    }
                    if (methodConfig != null) {
                        DataMap map = activityInst.getFormValues();
                        Object dbMap = map.getDAO(proxy.getFieldName(), daoService.getEntityClass().getCtClass());
                        tableFormTab.getTagVar().putAll(BeanMap.create(dbMap));
                        tableFormTab.setEuClassName(methodConfig.getEUClassName());
                    }
                    formTabs.add(tableFormTab);
                }

            }


            if (formTabs.size() > 0) {
                formTabsTree.setData(formTabs);
                formTabsTree.setIds(Arrays.asList(formTabs.get(0).getFormname()));
            }
            formTabsTree.setCtx(baseMap);

        } catch (BPMException e) {
            e.printStackTrace();
        } catch (JDSException e) {
            e.printStackTrace();
        }

        return formTabsTree;
    }

    @MethodChinaName(cname = "监控")
    @RequestMapping(method = RequestMethod.POST, value = "processAdmin")
    @GridViewAnnotation()
    @DialogAnnotation
    @ModuleAnnotation(imageClass = "bpmfont bpmgongzuoliujiankong", caption = "监控")
    @APIEventAnnotation(customRequestData = RequestPathEnum.treegridrow)
    public @ResponseBody
    ListResultModel<List<ActivityInstListView>> getMyActivityInstList(String processDefVersionId) {
        ListResultModel<List<ActivityInstListView>> result = new ListResultModel<List<ActivityInstListView>>();
        try {
            ProcessDefVersion version = getClient().getProcessDefVersion(processDefVersionId);
            BPMCondition condition = new BPMCondition(BPMConditionKey.PROCESSDEF_ID,
                    Operator.EQUALS, version.getProcessDefId());
            condition.addOrderBy(new Order(BPMConditionKey.ACTIVITYINST_ARRIVEDTIME, false));
            ListResultModel<List<ActivityInst>> activityInstList = getClient().getActivityInstList(condition, RightConditionEnums.CONDITION_ALLWORK, null, null);
            result = PageUtil.changPageList(activityInstList, ActivityInstListView.class);
        } catch (BPMException e) {
            result = new ErrorListResultModel();
            ((ErrorListResultModel<List<ActivityInstListView>>) result).setErrdes(e.getMessage());
            ((ErrorListResultModel<List<ActivityInstListView>>) result).setErrcode(e.getErrorCode());
            e.printStackTrace();
        }

        return result;

    }


    /**
     * @return
     */
    private WorkflowClientService getClient() {

        WorkflowClientService client = EsbUtil.parExpression("$BPMC", WorkflowClientService.class);

        return client;
    }
}

